package service

import (
	"context"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
	"monitoring-api/models"
	"monitoring-api/serializer"
	"sort"
	"strconv"
	"strings"
)

type ActionCondition struct {
	Duration string `json:"duration"` // 停留时间，查询时间范围内的数据，格式为两个数字，中间用_分割，单位毫秒
	IP       string `json:"ip"`       // ip，查询ip中包含参数的数据
	Time     string `json:"time"`     // 时间范围，查询起止时间内的数据，格式为两个时间戳，中间用_分割
	URL      string `json:"url"`      // 页面路径，查询路径中包含参数的数据
}

type GetActionLogsService struct {
	WebID     int64 `json:"web_id"`
	Page      int64 `json:"page"`
	Condition ActionCondition
}

func (service *GetActionLogsService) Query() serializer.Response {
	logs := make([]models.UserAction, 0)
	//处理查询语句
	err, ip, startTime, endTime, DstartTime, DendTime, url := service.handleCondition()
	//查询语句
	var filter bson.D
	if ip != "" {
		filter = bson.D{{"webid", service.WebID},
			{"time", bson.D{{"$gt", startTime}}},
			{"time", bson.D{{"$lte", endTime}}},
			{"ip", ip},
			{"url", bson.D{{"$regex", url}}},
			{"duration", bson.D{{"$gt", DstartTime}}},
			{"duration", bson.D{{"$lte", DendTime}}},
		}
	} else {
		filter = bson.D{{"webid", service.WebID},
			{"time", bson.D{{"$gt", startTime}}},
			{"time", bson.D{{"$lte", endTime}}},
			{"url", bson.D{{"$regex", url}}},
			{"duration", bson.D{{"$gt", DstartTime}}},
			{"duration", bson.D{{"$lte", DendTime}}},
		}
	}
	opts := options.Find().SetSkip((service.Page - 1) * 10).SetLimit(10)
	//获取文档总数
	total, err := models.Mongo.Collection("actions").CountDocuments(context.TODO(), filter)
	//分页查询
	cursor, err := models.Mongo.Collection("actions").Find(context.TODO(), filter, opts)
	if err != nil {
		return serializer.Response{
			Code:    500,
			Message: "数据库查询错误",
			Error:   err.Error(),
		}
	}
	// display the results
	var results []bson.M
	if err = cursor.All(context.TODO(), &results); err != nil {
		return serializer.Response{
			Code:    500,
			Message: "服务器错误",
			Error:   err.Error(),
		}
	}
	for _, result := range results {
		log := models.UserAction{}
		log.Kind = result["kind"].(int64)
		log.Duration = result["duration"].(int64)
		log.IP = result["ip"].(string)
		log.Time = result["time"].(int64)
		log.Area = result["area"].(int64)
		log.URL = result["url"].(string)
		log.WebID = result["webid"].(int64)
		logs = append(logs, log)
	}
	//按时间降序排列
	sort.Slice(logs, func(x, y int) bool {
		return logs[x].Time > logs[y].Time
	})
	return serializer.BuildActionsResponse(logs, total, service.Page)
}

// 处理查询条件
func (service *GetActionLogsService) handleCondition() (error, string, int64, int64, int64, int64, string) {
	//处理时间
	time := strings.Split(service.Condition.Time, "_")
	startTime, err := strconv.ParseInt(time[0], 10, 64)
	if err != nil {
		return err, "", 0, 0, 0, 0, ""
	}
	endTime, err := strconv.ParseInt(time[1], 10, 64)
	if err != nil {
		return err, "", 0, 0, 0, 0, ""
	}
	//处理用户停留时间
	var DstartTime, DendTime int64
	if service.Condition.Duration != "" {
		DTime := strings.Split(service.Condition.Duration, "_")
		DstartTime, err = strconv.ParseInt(DTime[0], 10, 64)
		if err != nil {
			return err, "", 0, 0, 0, 0, ""
		}
		DendTime, err = strconv.ParseInt(DTime[1], 10, 64)
		if err != nil {
			return err, "", 0, 0, 0, 0, ""
		}
	} else {
		DstartTime = 0
		DendTime = 9999999
	}
	//处理ip
	var ip string
	if service.Condition.IP != "" {
		ip = service.Condition.IP
	} else {
		ip = ""
	}
	//处理url
	var url string
	if service.Condition.URL != "" {
		url = service.Condition.URL
	} else {
		url = ""
	}
	return err, ip, startTime, endTime, DstartTime, DendTime, url
}
